﻿#ifndef __INPUT_H__
#define __INPUT_H__

#include <bits/stdc++.h>
#include "Operation.h"
#include "ServerType.h"
#include "Parser.h"
#include <tuple>
#include <list>
#include <map>

using namespace std;

namespace hw {

    class Input {
    public:
        std::istream &input;
        int days;
        int next_day;
        int K;
    public:
        Input(std::istream &in) : input(in), next_day(0) {}

        /*!
         * 读取数据前面部分的类型信息，包括服务器类型、虚拟机类型
         * @param server_type_list
         * @param vm_type_dict
         */
        void read_type_data(vector<ServerType> &server_type_list,
                            unordered_map<string, Vmtype> &vm_type_dict) {
            //物理机类型数量
            std::string temp;
            std::getline(input, temp);
            int type_num = stoi((temp));

            // 读取所有物理机
            server_type_list.reserve(type_num);
            while (type_num--) {
                std::getline(input, temp);
                ServerType &&server_type = Parser::parse_server(temp);
                server_type_list.push_back(server_type);
            }

            //虚拟机类型数量
            std::getline(input, temp);
            int vm_num = stoi(temp);

            //读取虚拟机类型
            while (vm_num--) {
                std::getline(input, temp);
                Vmtype &&vm_type = Parser::parse_vm(temp);
                vm_type_dict[vm_type.name] = vm_type;
            }

            // 读取天数以及K
            std::getline(input, temp);
            vector<int> nums = Parser::parse_ints(temp, ' ');
            days = nums[0];
            K = nums[1];
        }

        /*!
         * 读取下一天的请求数据
         * 由于复赛限制，不能将所有操作统一读入，调用这个方法之前需要判断是否能够读，否则将会阻塞，造成超时
         * @return
         */
        vector<Operation> read_next_day_operation() {
            // 读取一天的操作数
            string line;
            std::getline(input, line);
            int op_num = stoi(line);
            vector<Operation> res;
            res.reserve(op_num);

            while (op_num--) {
                getline(input, line);
                res.push_back(Parser::parse_operation(line));
            }

            return res;
        }
    };
} // namespace hw
#endif // !__INPUT_H_
